import re

from app.services.ocr.utils.similarity import similar
from app.services.ocr.utils.text_processing import extract_ocr_options, extract_question_rich, normalize
from app.services.ocr.utils.utils import is_tf


def screen_text(query_text: str, results: list) -> list:
    """
    对 OCR 识别到的问题文本进行筛选匹配，返回可能匹配到的题目候选项。
    - 支持判断题、选择题的题型判断
    - 使用题干相似度和选项相似度进行双重过滤

    参数:
        query_text (str): OCR识别后的题目原文
        results (list): 数据库中提取出的题目列表，每个元素为dict

    返回:
        list: 匹配成功的题目信息列表

    """

    # 题干提取（去除多余信息用于相似度匹配）
    question_stem = extract_question_rich(query_text)
    tf_query_text = question_stem

    # 提取题型关键词（判断题 / 单选题 / 多选题）
    type_match = re.search(r'(判断题|单选题|多选题)', query_text)

    # 判断题不需要提取选项
    if not is_tf(query_text):
        # 选项提取
        ocr_options_text, ocr_options = extract_ocr_options(query_text)
    else:
        # 如果是“是非题”，通常 OCR 会附带 'N:错误Y:正确'，去除干扰
        tf_query_text = question_stem.replace('N:错误Y:正确', '')
        ocr_options_text = []

    filtered_results = []
    special_keywords = ['下列哪个指示灯', '如图所示','下列哪个标志','以下交通标志中']
    for ret in results:
        # 特殊题目直接跳过
        if '将车辆移至不妨碍交通的地点，按要求在来车方向设置三角警告牌，并报警' in ret.get('subject', ''):
            ret['noVerify'] = True
            filtered_results.append(ret)
            continue
        subject = ret.get('subject', '')
        if not subject:
            continue

        # 题型不匹配时跳过
        if type_match and ret.get('type_text') != type_match.group(0):
            continue

        # 提前计算题干相似度
        sim_score = similar(subject, tf_query_text)

        # 判断题处理：含“正确/错误”的直接按题干相似度判断
        options_text = ''.join([ret.get(f"option{opt}", "") for opt in ['A', 'B', 'C', 'D']])
        if is_tf(options_text):
            if sim_score >= 0.85:
                filtered_results.append(ret)
            continue

        # 特殊题型（如图所示/指示灯）处理
        if any(kw in subject and kw in question_stem for kw in special_keywords):
            if sim_score >= 0.8:
                ret['noVerify'] = True
                filtered_results.append(ret)
            continue

        # 普通题干匹配不足则跳过
        if sim_score < 0.8:
            continue

        # 选项相似度匹配
        db_options = [ret.get(f"option{opt}", "") for opt in ['A', 'B', 'C', 'D']]
        match_count = sum(
            any(similar(ocr_opt, db_opt) >= 0.7 for db_opt in db_options)
            for ocr_opt in ocr_options_text if ocr_opt
        )
        if match_count == 4:
            return [ret]

        # 若题干相似度很高，也保留
        if sim_score >= 0.90:
            filtered_results.append(ret)

    # 最后按题干相似度降序排列，提升最匹配结果靠前概率
    filtered_results.sort(
        key=lambda r: similar(r.get('subject', ''), question_stem),
        reverse=True
    )

    return filtered_results

